import logging
import os
import platform
import subprocess
import traceback

import sqlalchemy
from flask import Flask, json, jsonify, request
from flask_caching import Cache
from flask_sqlalchemy import SQLAlchemy
from marshmallow import ValidationError
from werkzeug.exceptions import HTTPException

from src.config.application import ApplicationConfig
from src.config.cache import CacheConfig
from src.config.logger import LoggerConfig
from src.config.mysql import MysqlConfig
from src.const.code import Code
from src.util.rs import Rs

# 全局 cache 实例（避免循环依赖）
cache = Cache()

# 全局 db 实例（避免循环依赖）
db = SQLAlchemy()


def create_app():
    app = Flask(__name__)

    # +-------------------
    # + 配置
    # +-------------------
    app.config.from_object(ApplicationConfig)
    app.config.from_object(MysqlConfig)
    app.config.from_object(CacheConfig)
    app.config.update({
        'APP_ABS_PATH': os.path.abspath(os.path.join(os.path.dirname(__file__), '..')),
    })
    app.debug = app.config.get('DEBUG')
    # print("DEBUG信息", app.config.get('DEBUG'), type(app.config.get('DEBUG')))

    # print(';;;;;;;;;;', app.config.get('SQLALCHEMY_DATABASE_URI'))
    # print(';;;;;;;;;;', app.config.get('SQLALCHEMY_TRACK_MODIFICATIONS'))
    # print(';;;;;;;;;;', app.config.get('SQLALCHEMY_ECHO'))
    # print(';;;;;;;;;;', app.config.get('CACHE_TYPE'))
    # print(';;;;;;;;;;', app.config.get('CACHE_REDIS_HOST'))
    # print(';;;;;;;;;;', app.config.get('CACHE_REDIS_PORT'))
    # print(';;;;;;;;;;', app.config.get('CACHE_REDIS_DB'))
    # print(';;;;;;;;;;', app.config.get('CACHE_REDIS_PASSWORD'))
    # print(';;;;;;;;;;', app.config.get('CACHE_THRESHOLD'))
    # print(';;;;;;;;;;', app.config.get('CACHE_KEY_PREFIX'))
    # print(';;;;;;;;;;', app.config.get('DEBUG'))
    # print(';;;;;;;;;;', app.config.get('PROJECT'))

    # +-------------------
    # + 配置日志
    # +-------------------
    LoggerConfig(
        app=app,
        log_dir=os.path.join(app.config.get("APP_ABS_PATH"), 'logs'),
        file_level=logging.NOTSET,
        console_level=logging.DEBUG,
        backup_count=14  # 保留14天日志
    )

    # +-------------------
    # + 缓存
    # +-------------------
    cache.init_app(app)

    # +-------------------
    # + MySQL
    # +-------------------
    db.init_app(app)

    # +-------------------
    # + 前置过滤器
    # +-------------------
    @app.before_request
    def before_request():
        # app.logger.info("before_request 前置过滤器")
        pass

    # +-------------------
    # + 处理错误
    # +-------------------
    @app.errorhandler(Exception)
    def handle_exception(e):
        # HTTP错误
        if isinstance(e, HTTPException):
            return e
        # 数据库相关异常
        elif isinstance(e, sqlalchemy.exc.SQLAlchemyError):
            app.logger.error("数据库错误: %s", traceback.format_exc())
            return jsonify(Rs(
                Code.SYSTEM_ERROR,
                "数据库操作失败",
            ).to_dict()), 500
        # 参数验证异常
        elif isinstance(e, ValidationError):  # 假设使用了验证库
            return jsonify(Rs(
                Code.PARAM_ERROR,
                str(e),
            ).to_dict()), 400
        # 系统错误
        else:
            app.logger.error("系统错误: %s", traceback.format_exc())
            return jsonify(Rs(
                Code.SYSTEM_ERROR,
                Code.message(Code.SYSTEM_ERROR) + ": " + str(e),
            ).to_dict()), 500

    # +-------------------
    # + HTTP错误处理
    # +-------------------
    @app.errorhandler(HTTPException)
    def handle_http_exception(e):
        response = e.get_response()
        response.content_type = "application/json"
        response.data = json.dumps(Rs(
            e.code,
            e.name,
            {
                "message": e.description,
                "request": {
                    "url": request.url,
                    "method": request.method,
                    "headers": dict(request.headers),
                    "ip": request.remote_addr,
                },
            }
        ).to_dict())
        # app.logger.info("HTTP错误: %s", request.url)
        return response

    # +-------------------
    # + 注册http蓝图
    # +-------------------
    from src.http.specimen import BlueprintHttpSpecimen
    from src.http.example import BlueprintHttpExample
    app.register_blueprint(BlueprintHttpSpecimen, url_prefix="/specimen")
    app.register_blueprint(BlueprintHttpExample, url_prefix="/example")

    # +-------------------
    # + 注册console蓝图
    # +-------------------
    from src.console.deepseek import BlueprintConsoleDeepseek
    from src.console.hello import BlueprintConsoleHello
    app.register_blueprint(BlueprintConsoleDeepseek)
    app.register_blueprint(BlueprintConsoleHello)

    # +-------------------
    # + 启动信息
    # +-------------------
    app.logger.info("🚀 「" + app.config.get('PROJECT') + "」启动成功！")

    # +-------------------
    # + 首页
    # +-------------------
    @app.route('/')
    def index():
        """
        首页
        """
        # 执行 pip list 命令
        pip_list = subprocess.run(['pip', 'list'], capture_output=True, text=True)
        pip_list_output = pip_list.stdout

        # 执行 python --version 命令
        python_version = subprocess.run(['python', '--version'], capture_output=True, text=True)
        python_version_output = python_version.stdout

        return Rs(Code.OK, app.config.get('PROJECT'), {
            'os': platform.system(),
            'python': python_version_output.replace("\n", ""),
            'libraries': pip_list_output.split("\n"),
            'document': '/api/doc'
        }).to_dict()

    return app
